﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEditor;

[InitializeOnLoad]
public class SoarDHierarchy
{
    static GameObject[] SelectionObjs;
    static Dictionary<GameObject, Rect> GO2Rect = new Dictionary<GameObject, Rect>();

    static SoarDHierarchy()
    {
        EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
        Selection.selectionChanged += OnSelectionChanged;
    }

    static void HierarchyWindowItemOnGUI(int instanceID, Rect selectionRect)
    {
        Object obj = EditorUtility.InstanceIDToObject(instanceID);

        CustomItem(selectionRect, obj);
    }

    static void CustomItem(Rect selectionRect, Object obj)
    {
        if (obj is GameObject)
        {
            GameObject go = obj as GameObject;

            if (!GO2Rect.ContainsKey(go))
            {
                GO2Rect.Add(go, selectionRect);
            }

            ShowOrHideGameObject(go, selectionRect);
            CalculateChildNode(go, selectionRect);
        }
    }

    static void ShowOrHideGameObject(GameObject go, Rect selectionRect)
    {
        Rect r = new Rect(selectionRect);
        r.x += r.width - 30;
        var gr = go.GetComponent<Graphic>();
        if (EditorApplication.isPlaying && gr != null && (gr is SDImage || gr is SoarDText))
        {
            Rect r2 = new Rect(selectionRect);
            r2.x = r.x - 15;
            r2.width = 15;
            bool isCull = GUI.Toggle(r2, !gr.canvasRenderer.cull, "");
            if (isCull != !gr.canvasRenderer.cull)
            {
                if (SelectionObjs != null && SelectionObjs.Length > 1)
                {
                    for (int i = 0; i < SelectionObjs.Length; i++)
                    {
                        if (SelectionObjs[i] != go)
                        {
                            var _gr = SelectionObjs[i].GetComponent<Graphic>();
                            if (_gr != null && (_gr is SDImage || _gr is SoarDText))
                            {
                                _gr.SetActive(isCull);
                            }
                        }
                    }
                }
            }
            if (gr.canvasRenderer.cull != !isCull)
            {
                gr.SetActive(isCull);
            }
        }

        bool isActive = GUI.Toggle(r, go.activeSelf, "");
        if (isActive != go.activeSelf)
        {
            if (SelectionObjs != null && SelectionObjs.Length > 1)
            {
                for (int i = 0; i < SelectionObjs.Length; i++)
                {
                    if (SelectionObjs[i] != go)
                    {
                        SelectionObjs[i].SetActive(isActive);
                    }
                }
            }
        }
        go.SetActive(isActive);
    }

    static void CalculateChildNode(GameObject go, Rect selectionRect)
    {

        Transform trans = go.transform;

        Rect r = new Rect(selectionRect);
        r.x -= 50;
        int childCount = 0;
        Transform[] childs = trans.GetComponentsInChildren<Transform>(true);

        childCount = childs.Length - 1;
        TextAnchor ta = GUI.skin.label.alignment;
        GUI.skin.label.alignment = TextAnchor.MiddleRight;
        GUI.Label(r, childCount == 0 ? "" : childCount.ToString());
        GUI.skin.label.alignment = ta;
    }

    static void OnSelectionChanged()
    {
        SelectionObjs = Selection.gameObjects;
    }
}
